package com.project.shangqi.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.project.shangqi.dto.LoginParam;
import com.project.shangqi.dto.LoginResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class HttpUtil {

    private String url;

    private String token;

    private Integer timeout;


    public HttpUtil(String url, Integer timeout) {
        this.url = url;
        this.timeout = timeout;
    }

    public HttpUtil(String url, String token, Integer timeout) {
        this.url = url;
        this.token = token;
        this.timeout = timeout;
    }

    public LoginResult doLogin(LoginParam param) throws Exception {
        LoginResult result = null;
        try {
            HttpEntity httpEntity = buildPostEntity(param);
            HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
            httpRequestFactory.setConnectionRequestTimeout(this.timeout);
            httpRequestFactory.setConnectTimeout(this.timeout);
            httpRequestFactory.setReadTimeout(this.timeout);
            httpRequestFactory.setBufferRequestBody(false);
            RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
            ResponseEntity<String> response = restTemplate.exchange(this.url, HttpMethod.POST, httpEntity, String.class);
            if (response.getStatusCode() != HttpStatus.OK) {
                throw new Exception("请求失败:" + response.getStatusCodeValue());
            }
            if (!StringUtils.isEmpty(response.getBody()) && response.getBody().split("&").length == 3) {
                result = new LoginResult();
                result.setAccess_token(response.getBody().split("&")[0].replace("access_token=", ""));
                result.setId(response.getBody().split("&")[1].replace("id=", ""));
                result.setExpires_in(Long.parseLong(response.getBody().split("&")[2].replace("expires_in=", "")));
            }
            return result;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    public <T> Object getUrl(Class<T> clazz, Integer type) throws Exception {
        try {
            HttpEntity httpEntity = buildGetEntity();
            HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
            httpRequestFactory.setConnectionRequestTimeout(this.timeout);
            httpRequestFactory.setConnectTimeout(this.timeout);
            httpRequestFactory.setReadTimeout(this.timeout);
            httpRequestFactory.setBufferRequestBody(false);
            RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
            ResponseEntity<byte[]> response = restTemplate.exchange(this.url, HttpMethod.GET, httpEntity, byte[].class);
            if (response.getStatusCode() != HttpStatus.OK) {
                throw new Exception("请求失败:" + response.getStatusCodeValue());
            }
            if (response.getBody().length > 0) {
                String result = new String(response.getBody(), "UTF-8");
                if (type == 0) {
                    return JSONObject.parseObject(result, clazz);
                } else if (type == 1) {
                    JSONObject jsonObject = JSONArray.parseArray(result).getJSONObject(0);
                    return jsonObject.toJavaObject(clazz);
                } else {
                    JSONArray array = JSONArray.parseArray(result);
                    return array.toJavaList(clazz);
                }
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    private <T> HttpEntity buildPostEntity(LoginParam param) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/x-www-form-urlencoded");
        MultiValueMap dataMap = new LinkedMultiValueMap();
        Class<?> paramClass = param.getClass();
        for (Field field : paramClass.getDeclaredFields()) {
            Object value = getProperty(param, field.getName());
            if (value != null) {
                dataMap.add(field.getName(), value);
            }
        }
        return new HttpEntity(dataMap, headers);
    }

    private <T> HttpEntity buildGetEntity() throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept", "application/json");
        headers.add("Authorization", "Bearer " + token);
        return new HttpEntity(headers);
    }

    public static <T> Object getProperty(Object bean, String propertyName) throws Exception {
        PropertyDescriptor pd = new PropertyDescriptor(propertyName, bean.getClass());
        return pd.getReadMethod().invoke(bean);
    }
}
